package com.github.limit.util;

import com.github.limit.annotation.Limit;
import org.springframework.util.CollectionUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: wangdejun
 * @create: 2019-10-14 16:14
 **/
public class LimitUtils {


    // 去掉重复的注解，并进行排序
    public static List<Annotation> mergeAndSort(List<Annotation> retainAnnotations, List<Annotation> filterAnnotations) {
        if (CollectionUtils.isEmpty(retainAnnotations)) {
            if (CollectionUtils.isEmpty(filterAnnotations)) {
                return new ArrayList<>();
            }
            retainAnnotations = filterAnnotations;
        } else {
            final List<Class<? extends Annotation>> annotations = retainAnnotations
                    .stream().map(annotation -> annotation.annotationType())
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(filterAnnotations)) {
                List<Annotation> collect = filterAnnotations.stream()
                        .filter(annotation -> {
                                    return !annotations.contains(annotation.annotationType());
                                }
                        ).collect(Collectors.toList());

                if (!CollectionUtils.isEmpty(collect)) {
                    retainAnnotations.addAll(collect);
                }
            }

        }
        return retainAnnotations.stream().sorted(Comparator.comparingInt(LimitUtils::getOrderValue)).collect(Collectors.toList());
    }


    public static int getOrderValue(Annotation annotation) {
        Integer integer = getAnnotationValue(annotation, "order");
        return Optional.ofNullable(integer).map(value -> value).orElse(0);
    }

    public static <T> T getAnnotationValue(Annotation annotation, final String methodName) {
        try {
            Method order = annotation.annotationType().getDeclaredMethod(methodName);
            return (T) order.invoke(annotation);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 过滤掉不被Limit标注的注解
    public static List<Annotation> filterAnnotation(Annotation[] annotations) {
        return filterAnnotation(annotations, Limit.class);
    }


    // 过滤掉不被clazz标注的注解
    public static List<Annotation> filterAnnotation(Annotation[] annotations, Class<? extends Annotation> clazz) {
        return Stream.of(annotations).filter(annotation ->
                annotation.annotationType().isAnnotationPresent(clazz)
        ).collect(Collectors.toList());
    }


    public static String replaceAndSbuLast(String key) {
        key = key.replaceAll(":{2,}", ":");
        if(key.startsWith(":")) {
            key = key.substring(key.indexOf(":") + 1);
        }
        if(key.endsWith(":")) {
            key = key.substring(0,key.lastIndexOf(":"));
        }
        return key;
    }

}
